home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / wdef / wdefpatch.c next >
Encoding:
C/C++ Source or Header  |  1995-04-01  |  12.0 KB  |  463 lines  |  [TEXT/CWIE]

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ©1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.     
  11.     Roberto Avanzi (independent programmer), June 18, 1992
  12.     Added support for tracking the extra part, in a way similar to the one used
  13.     by the system.
  14.     given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
  15.     
  16.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  17.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  18.     
  19. *******************************************/
  20.  
  21. #ifdef MPW
  22. #pragma segment WDEFPatch
  23. #endif
  24.  
  25. #include "wind.h"
  26. #include "wdefpatch.proto.h"
  27. #include "tnae.h"
  28.  
  29. static void drawicon(short id, Rect *dest);
  30.  
  31. /* 931112, ragge, NADA, KTH */
  32. static void drawSize(Rect *wSize, WindowPtr window);
  33.  
  34. /* add 2 to this when checking with FindWindow() ! */
  35.  
  36. #define kOurHit    32
  37.  
  38.  
  39. /* 
  40.  * this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  41.  * and stores the old handle to the WDEF
  42.  */
  43.  
  44. typedef struct {
  45. #ifdef __powerpc__
  46.     RoutineDescriptor rd;
  47. #else
  48.     short jmpInst;
  49.     ProcPtr patchAddr;
  50. #endif
  51.     Handle oldAddr;
  52.     Boolean partState;    /* roberto avanzi jun 18 1992 */
  53.     long ourA5;
  54.     struct WindRec *tw;
  55. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  56.  
  57.  
  58. /* 
  59.  * RePatchWindowWDEF
  60.  * this adjusts the tw pointer for a patched window
  61.  * We have to do this since the tw for a window can change when other
  62.  * windows are killed.
  63.  */
  64. void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  65. {
  66.     WDEFPatchHndl wdPatch;
  67.  
  68.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  69.     (**wdPatch).tw = tw;
  70. }
  71.  
  72.  
  73. /*
  74.  * GetPatchStuffHandle
  75.  * This returns the handle to our patch block so we can release it
  76.  * when killing windows. The tw is verified to insure that this
  77.  * window is really patched.
  78.  */
  79. Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw)
  80. {
  81.     WDEFPatchHndl wdPatch;
  82.  
  83.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  84.     if ((**wdPatch).tw == tw)
  85.         return ((Handle)wdPatch);
  86.     else
  87.         return ((Handle)0);
  88. }
  89.  
  90.  
  91. #ifdef __powerpc__
  92. enum {
  93.     uppMyWDEFPatch = kPascalStackBased
  94.         | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  95.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  96.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
  97.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short)))
  98.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  99. };
  100. #endif
  101.  
  102. pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param)
  103. {
  104.     WDEFPatchHndl wdPatch;
  105.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  106.     Handle oldWDEF;
  107.     long result;
  108.     Rect ourRect,ourElementRect;
  109.     GrafPtr    savePort;
  110.     GrafPtr aPort;
  111.     RgnHandle aRgn;
  112.     Rect aRect;
  113.     struct WindRec *tw;
  114.     long appA5, saveA5;
  115.     
  116.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  117.     appA5 = (**wdPatch).ourA5;
  118.     saveA5 = SetA5(appA5);
  119.  
  120.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  121.     /* our 16x16 rectangle */
  122.     SetRect(&ourElementRect,ourRect.right-42,ourRect.top+1,ourRect.right-26,ourRect.top+17);
  123.     
  124.     tw = (**wdPatch).tw;
  125.  
  126.     oldWDEF = (**wdPatch).oldAddr;
  127.     HLock(oldWDEF);
  128.     wdefProc = (void *)*oldWDEF;
  129.     wdefProc = (void *)StripAddress(wdefProc);
  130.  
  131.     /* 
  132.      * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
  133.      * the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
  134.      * Suppose You click once in the grow icon and DO NOT resize the window.
  135.      * (remember, just click and do not move the mouse in the meantime).
  136.      * Then you click on the added part. That part is tracked in the right way,
  137.      *                             *    BUT   *
  138.      * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
  139.      * of FUN. Sadly, cannot find its place in any useful app. Therefore we
  140.      * do this check.
  141.      * APPLE says: if you write your own WDEF and receive unknown messages, do not
  142.      *             do anything. pass along and do NOTHING.
  143.      * APPLE does: we get something new ? therefore we process it anyway, just to
  144.      *             keep developers writing workarounds and keep their minds afresh.
  145.      * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
  146.      */
  147.     if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) {
  148. #ifdef __powerpc__
  149.         result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param);
  150. #else
  151.         result = (wdefProc)(varCode,window,message,param);
  152. #endif
  153.     }
  154.  
  155.     if (((WindowPeek)window)->visible)
  156.     if (((WindowPeek)window)->hilited)
  157.     {
  158.         switch (message) {
  159.             case wDraw:
  160.                 GetPort(&savePort);
  161.                 GetWMgrPort(&aPort);
  162.                 SetPort(aPort);
  163.                 aRgn = NewRgn();
  164.                 GetClip(aRgn);
  165.                 SetRect(&aRect,-32000,-32000,32000,32000);
  166.                 ClipRect(&aRect);
  167.                 switch ( (short) param ) {    // Roberto Avanzi 18-06-1992: support for 
  168.                                             // tracking of the new part
  169.                     case 0:
  170.                         (**wdPatch).partState = false;
  171.  
  172.                     case kOurHit:
  173.                         PenNormal();                            // draw our part
  174.     
  175.                          if (tw->aedata != NULL) {
  176.                             tnParams *ae = (tnParams *)tw->aedata;
  177.  
  178.                              if (ae->encrypting || ae->decrypting) {
  179.                                  /* 
  180.                                   * erase 18 x 11. This gives us a 1 pixel margin
  181.                                   * on the left and right, and matches the mask that
  182.                                   * we're using in our crsr resources.
  183.                                   */
  184.                                  InsetRect(&ourElementRect, -1, 0);
  185.                                  ourElementRect.top += 3;
  186.                                  ourElementRect.bottom -= 2;
  187.                                  EraseRect(&ourElementRect);
  188.                                  ourElementRect.top -= 3;
  189.                                  ourElementRect.bottom += 2;
  190.                                  InsetRect(&ourElementRect, 1, 0);
  191.                              }                        
  192.                              if (ae->encrypting && ae->decrypting)
  193.                                  drawicon(lockcrsr, &ourElementRect);
  194.                              else if (ae->encrypting)
  195.                                  drawicon(rightcrsr, &ourElementRect);
  196.                              else if (ae->decrypting)
  197.                                  drawicon(leftcrsr, &ourElementRect);
  198.                          }
  199.                         break;
  200.                         
  201.                     default:
  202.                         break;
  203.                 }
  204.                 SetClip(aRgn);
  205.                 DisposeRgn(aRgn);
  206.                 SetPort(savePort);
  207.                 break;
  208.  
  209.                 // removed this test so that one can move the window
  210.                 // also when clicking on the icon area.
  211.                 // 931112, ragge, NADA, KTH
  212. #ifdef NOTDEF
  213.             case wHit:
  214.                 hitPt = (Point *)¶m;                    // hit test our part
  215.                 if (PtInRect(*hitPt,&ourElementRect))
  216.                 {
  217.                     //result =  kOurHit;
  218.                 }
  219.                 break;
  220. #endif
  221.             
  222.             case wGrow:        /* 931112, ragge, NADA, KTH */
  223.                 drawSize((Rect *) param, window);
  224.                 break;
  225.  
  226.             default:
  227.                 break;
  228.         }    // switch
  229.     }    //    if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
  230.     HUnlock(oldWDEF);
  231.     
  232.     SetA5(saveA5);
  233.     
  234.     return result;
  235. }
  236.  
  237.  
  238. #ifdef __powerpc__
  239. RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch);
  240. #endif
  241.  
  242. /* 
  243.  * this installs the WDEF patch into a window 
  244.  */
  245. void PatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  246. {
  247.     WDEFPatchHndl wdefHndl;
  248.     WDEFPatchPtr wdefPatch;
  249.     Handle oldAddr;
  250.     unsigned long wdefEntry;
  251.     
  252.     wdefHndl = (WDEFPatchHndl)myNewHandle(sizeof(WDEFPatch));
  253.  
  254.     oldAddr = ((WindowPeek)window)->windowDefProc;
  255.     if (GetMMUMode()) // 32-bit
  256.         wdefEntry = (unsigned long)wdefHndl;
  257.     else
  258.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  259.  
  260.     HLock((Handle)wdefHndl);
  261.     wdefPatch = *wdefHndl;
  262.     wdefPatch->oldAddr = oldAddr;
  263. #ifdef __powerpc__
  264.     BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd));
  265. #else
  266.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  267.     wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch;
  268. #endif
  269.     wdefPatch->ourA5 = (long)LMGetCurrentA5();        /* Use universal access (RW) */
  270.     wdefPatch->tw = tw;
  271.  
  272.     HUnlock((Handle)wdefHndl);
  273.  
  274.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  275. }
  276.  
  277.  
  278. /*
  279.  * drawicon
  280.  */
  281. void drawicon (short id, Rect *dest)
  282. {
  283.     long qdv;
  284.     Handle ih = 0;
  285.     Rect source_rect;
  286.     BitMap mask_bitmap;
  287.     GrafPtr local_port;
  288.     PixMap *pm;
  289.     Ptr colormap;
  290.     CCrsr *ccrsr;
  291.     BitMap src_bitmap;
  292.  
  293.     GetPort(&local_port);
  294.  
  295.     ih = GetResource ('crsr', id);                /* color cursor */
  296.     if (!ih)
  297.         return;
  298.     DetachResource(ih);        /* ... need to save handle somewhere ... */
  299.     HLock(ih);                /* ... to avoid reloading the resource all the time */
  300.  
  301.     /* 
  302.      * Set source Rect and intialize source BitMaps. 
  303.      * A few PixMap fields must be munged;
  304.      */
  305.     SetRect (&source_rect, 0, 0, 16, 16);
  306.     
  307.     ccrsr = (CCrsr *)(*ih);
  308.  
  309.     mask_bitmap.bounds = source_rect;
  310.     mask_bitmap.rowBytes = 2;
  311.     mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */
  312.     
  313.     /*
  314.      * if gestalt fails or no color quickdraw, just use the b/w bitmap.
  315.      */
  316.     if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) {
  317.         src_bitmap.bounds = source_rect;
  318.         src_bitmap.rowBytes = 2;
  319.         src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data;
  320.         CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest,
  321.                  srcCopy, nil);    
  322.     } else {
  323.         pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap);
  324.         pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData);
  325.             colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable);
  326.         pm->pmTable = (CTabHandle) &colormap;        /* handle to colormap */
  327.  
  328.         /* 
  329.          * Draw the crsr using its mask. 
  330.          * Do we need the mask ??? ...
  331.          */
  332.         CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits),
  333.                  &source_rect, &source_rect, dest);
  334.     }
  335.  
  336. //    HUnlock(ih);
  337. //    ReleaseResource((Handle)ih);
  338.     DisposHandle((Handle)ih);
  339. }
  340.  
  341. /* 931112, ragge, NADA, KTH */
  342. #define    HOFFSET    2
  343. #define VOFFSET    2
  344. static Rect gGrowTextBox;
  345. static Rect gGrowTextBoxInset;
  346. Boolean gDoGrowSize = false;
  347. static struct growSavedStruct {
  348.     Point charSize;
  349.     Point charInset;
  350.     Boolean eraseIt;
  351.  
  352.     PenState    savedPen;
  353.     short txFont;
  354.     Style txFace;
  355.     short txMode;
  356.     short txSize;
  357. } gGrowSaved;
  358.  
  359. /* 931112, ragge, NADA, KTH */
  360. void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize)
  361. {
  362.     GrafPtr    savedPort;
  363.     FontInfo fInfo;
  364.  
  365.     GetPort(&savedPort);
  366.     SetPort(window);
  367.         
  368.     gGrowSaved.charSize.h = hCharSize;
  369.     gGrowSaved.charSize.v = vCharSize;
  370.     gGrowSaved.charInset.h = hCharInset;
  371.     gGrowSaved.charInset.v = vCharInset;
  372.  
  373.     if(gGrowSaved.charSize.h == 0)    // don't want zero-div
  374.         gGrowSaved.charSize.h = 1;
  375.     if(gGrowSaved.charSize.v == 0)
  376.         gGrowSaved.charSize.v = 1;
  377.         
  378.     gGrowSaved.eraseIt = false;
  379.     
  380.     GetPenState(&gGrowSaved.savedPen);
  381.     
  382.     gGrowSaved.txFont = window->txFont;
  383.     gGrowSaved.txFace = window->txFace;
  384.     gGrowSaved.txMode = window->txMode;
  385.     gGrowSaved.txSize = window->txSize;
  386.  
  387.     PenNormal();
  388.     TextFont(1);
  389.     TextSize(9);
  390.     TextFace(0);
  391.     TextMode(srcCopy);
  392.     
  393.     GetFontInfo(&fInfo);
  394.  
  395.     gGrowTextBox.top = VOFFSET;
  396.     gGrowTextBox.left = HOFFSET;
  397.     gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3;    // Yes, 3!
  398.     gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6;
  399.     gGrowTextBoxInset = gGrowTextBox;
  400.     InsetRect(&gGrowTextBoxInset, 1, 1);
  401.     
  402.     gDoGrowSize = true;
  403.     
  404.     SetPort(savedPort);
  405. }
  406.  
  407. /* 931112, ragge, NADA, KTH */
  408. void cleanupForGrow(WindowPtr window)
  409. {
  410.     GrafPtr    savedPort;
  411.     GetPort(&savedPort);
  412.     SetPort(window);
  413.     
  414.     gDoGrowSize = false;
  415.     
  416.     InvalRect(&gGrowTextBox);
  417.     
  418.     SetPenState(&gGrowSaved.savedPen);
  419.     
  420.     window->txFont = gGrowSaved.txFont;
  421.     window->txFace = gGrowSaved.txFace;
  422.     window->txMode = gGrowSaved.txMode;
  423.     window->txSize = gGrowSaved.txSize;
  424.     
  425.     SetPort(savedPort);
  426. }
  427.  
  428. /* 931112, ragge, NADA, KTH */
  429. void drawSize(Rect *wSize, WindowPtr window)
  430. {
  431.     unsigned char string[50], yValLen;
  432.     GrafPtr savedPort;
  433.     
  434.     if(!gDoGrowSize)
  435.         return;
  436.  
  437.     GetPort(&savedPort);
  438.     SetPort(window);
  439.     
  440.     if(!gGrowSaved.eraseIt) {
  441.         NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string);
  442.         string[++string[0]] = ' ';
  443.         string[++string[0]] = '*';
  444.         NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1);
  445.         yValLen = string[string[0] + 1];
  446.         string[++string[0]] = ' ';
  447.         string[0] += yValLen;
  448.         TextBox(string + 1, string[0], &gGrowTextBoxInset, 1);
  449.         FrameRect(&gGrowTextBox);
  450.     } else {
  451.         Rect rGlob = gGrowTextBox;
  452.         LocalToGlobal((Point *) &(rGlob.top));
  453.         LocalToGlobal((Point *) &(rGlob.bottom));
  454.     }
  455.     
  456.     gGrowSaved.eraseIt = !gGrowSaved.eraseIt;
  457.  
  458.     SetPort(savedPort);
  459. }
  460.  
  461. //empty function so we can load this high at initTime
  462. void loadWDEF(void) { }
  463.